ddddllllooooppppeeeennnn is one of a family of routines that give the user direct access to
the dynamic linking facilities. These routines are available in a library
which is loaded if the option ----llllcccc is used with cccccccc , ffff77777777 or lllldddd.
ddddllllooooppppeeeennnn makes a shared object available to a running process. ddddllllooooppppeeeennnn
returns to the process a _h_a_n_d_l_e which the process may use on subsequent
calls to ddddllllssssyyyymmmm and ddddllllcccclllloooosssseeee. This _h_a_n_d_l_e should not be interpreted in any
way by the process. _p_a_t_h_n_a_m_e is the path name of the object to be
opened; it may be an absolute path or relative to the current directory.
If the value of _p_a_t_h_n_a_m_e is 0, ddddllllooooppppeeeennnn makes the symbols contained in the
original aaaa....oooouuuutttt, and all of the objects that were loaded at program
startup with the aaaa....oooouuuutttt, available through ddddllllssssyyyymmmm.
When a shared object is brought into the address space of a process, it
may contain references to symbols whose addresses are not known until the
object is loaded. These references must be relocated before the symbols
can be accessed. The _m_o_d_e parameter governs when these relocations take
place and may have the following values:
RRRRTTTTLLLLDDDD____LLLLAAAAZZZZYYYY
Only references to data symbols are relocated when the object is
loaded. References to functions are not relocated until a given
function is invoked for the first time. This _m_o_d_e should result in
the best performance, since a process may not reference all of the
functions in any given shared object. RRRRTTTTLLLLDDDD____LLLLAAAAZZZZYYYY cannot be combined
with RRRRTTTTLLLLDDDD____NNNNOOOOWWWW.
RRRRTTTTLLLLDDDD____NNNNOOOOWWWW
All necessary relocations are performed when the object is first
loaded. This may result in some wasted effort if relocations are
performed for functions that are never referenced, but is useful for
programs that need to know as soon as an object is loaded that all
symbols referenced during execution are available. RRRRTTTTLLLLDDDD____NNNNOOOOWWWW cannot
be combined with RRRRTTTTLLLLDDDD____LLLLAAAAZZZZYYYY.
RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL
modifies the treatment of the symbols in the DSO being opened to be
identical to those of ssssggggiiii____ddddllllaaaadddddddd(). RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL may be or'd with
either RRRRTTTTLLLLDDDD____NNNNOOOOWWWW or RRRRTTTTLLLLDDDD____LLLLAAAAZZZZYYYY (RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL cannot be the mmmmooooddddeeee value
on its own). RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL See "NAMESPACE ISSUES" below for more on
the impact of using or not using RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL. With RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL the
Name resolution can become surprisingly complicated and non-intuitive in
the presence of programs or DSOs using ddddllllooooppppeeeennnn, ssssggggiiiiddddllllaaaadddddddd,
ssssggggiiii____ddddllllooooppppeeeennnn____vvvveeeerrrrssssiiiioooonnnn, or LLLLLLLL____DDDDEEEELLLLAAAAYYYY____LLLLOOOOAAAADDDD (the _l_d -_d_e_l_a_y__l_o_a_d option).
Any case in which there is only one definition of a symbol across all
loaded DSOs is simple: that definition is used if it is visible
(visibility is discussed below).
Name searches are done in the order of a single list, the rld-list. The
first rld-list entry is the program itself. Following that is the list
of DSOs currently in the runtime of the program. At program startup a
breadth-first list of DSOs in the program (and, recursively their library
lists) is formed in the rld-list. No DSO is added to the rld-list twice
(later encounters of a DSO in simply use the earlier occurrence, but see
NOTES below for an exception). For any DSO library list entry marked
LLLLLLLL____DDDDEEEELLLLAAAAYYYY____LLLLOOOOAAAADDDD the DSO referenced is not loaded at program startup.
The above name search rule has an exception. If a DSO is marked as
DT_SYMBOLIC (see the _l_d option ----BBBB ssssyyyymmmmbbbboooolllliiiicccc) then all name searches from
within that DSO begin at the DSO itself and continue with the standard
rld-list search.
When, as a result of a call to a function in a LLLLLLLL____DDDDEEEELLLLAAAAYYYY____LLLLOOOOAAAADDDDed DSO, that
DSO is loaded, the new DSO is added at the end of the rld-list (if it has
any entries in its library list that are not marked LLLLLLLL____DDDDEEEELLLLAAAAYYYY____LLLLOOOOAAAADDDD the
non-LLLLLLLL____DDDDEEEELLLLAAAAYYYY____LLLLOOOOAAAADDDD DSOs are added, recursively (breadth-first)). Thus,
depending on the order of calls to delay-loaded DSOs, the order of DSOs
on the rld-list may be different from one run of a program to the next.
The order of DSOs in the rld-list may not match the order in any given
library list because if a DSO is already in the rld-list it is not added
a second time to the rld-list.
As a result of the rule that the search order is rld-list order, the
symbol found can be surprising. Consider a symbol A found in DSOs B and
C and DSO B is before DSO C in E's liblist while DSO B is after DSO C in
F's liblist. Lets specify that neither DSO B nor DSO C are otherwise
referenced. If DSO E is ddddllllooooppppeeeennnn((((............RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL))))ed before DSO F then the A
from DSO B is found by ddddllllssssyyyymmmm from either handle. While if DSO F is
ddddllllooooppppeeeennnn((((............RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL))))ed before DSO E then the A from DSO C is found by
ddddllllssssyyyymmmm from either handle. On the other hand, if only one of the DSOs E
or F is ddddllllooooppppeeeennnn((((............RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL))))ed then one gets DSO B's A from DSO E's
handle and one gets DSO C's A from DSO F's handle.
Note that _d_l_c_l_o_s_e does not cause any reordering of the rld-list: when the
last handle (direct or indirect) on a DSO is _d_l_c_l_o_s_ed the DSO is removed
from the rld-list. Before the final _d_l_c_l_o_s_e the DSO remains where it was
DSOs loaded by a single invocation of ddddllllooooppppeeeennnn may import symbols from one
another or from any DSO which is globally-visible, but DSOs loaded by one
ddddllllooooppppeeeennnn invocation may not directly reference symbols from DSOs loaded by
a different ddddllllooooppppeeeennnn invocation. Those symbols may, however, be referenced
indirectly using ddddllllssssyyyymmmm.
Globally-visible DSOs are those added at program startup or via delay-
load from a globally-visible object. In addition, any DSO added by
ssssggggiiiiddddllllaaaadddddddd or ddddllllooooppppeeeennnn((((............RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL............)))) or
ssssggggiiiiddddllllooooppppeeeennnn____vvvveeeerrrrssssiiiioooonnnn((((............RRRRTTTTLLLLDDDD____GGGGLLLLOOOOBBBBAAAALLLL............)))) is globally-visible.
Even in a globally-visible DSO a symbol is invisible to any access from
outside the DSO if the symbol is marked SSSSTTTTOOOO____HHHHIIIIDDDDDDDDEEEENNNN (see the _l_d options
----hhhhiiiiddddddddeeeennnn____ssssyyyymmmmbbbboooollll or ----hhhhiiiiddddeeeessss____ffffiiiilllleeee for example). From within a DSO, all
symbols in that DSO are visible. From within a DSO, all globally-visible
symbols are visible.
Consider a set of DSOs.
ld -shared -all F.a -o F.so
ld -shared -all G.a -o G.so
ld -shared -all E.a F.so G.so -o E.so
ld -shared -all H.a F.so -o H.so
Say a program does dlopen("E.so",RTLD_LAZY) and and
dlopen("H.so",RTLD_LAZY) and uses _d_l_s_y_m to find functions through the two
_h_a_n_d_l_es and calls these two functions. Say each of these calls a function
that calls ff() in F.so. Say that ff() calls fg() which is only defined
in G.so. Logically one would say that the call through the function
accessed via E.so should resolve to fg() in G.so and one would think that
the call thru the function accessed via H.so should result in an
undefined function. However, _r_l_d does not attempt to determine (by
walking the run-time stack or other means) the exact call-stack to ff()
(the call-stack is not really enough: _r_l_d needs to know the _h_a_n_d_l_e used
to derive the calls!). The result of the call to fg() is undefined.
What happens is that fg() in G.so is called, since such would be legal if
the call path were thru E.so's _h_a_n_d_l_e. It is unwise to depend on such
3) any directory specified by the environment variable LLLLDDDD____LLLLIIIIBBBBRRRRAAAARRRRYYYY____PPPPAAAATTTTHHHH.
This environment variable should contain a colon-separated list of
directories, in the same format as the PPPPAAAATTTTHHHH variable [see sssshhhh(1)]. 64-bit
programs examine the variable LLLLDDDD____LLLLIIIIBBBBRRRRAAAARRRRYYYY66664444____PPPPAAAATTTTHHHH, and if it is not set
LLLLDDDD____LLLLIIIIBBBBRRRRAAAARRRRYYYY____PPPPAAAATTTTHHHH is examined. New 32-bit ABI programs examine the
variable LLLLDDDD____LLLLIIIIBBBBRRRRAAAARRRRYYYYNNNN33332222____PPPPAAAATTTTHHHH and if it is not set LLLLDDDD____LLLLIIIIBBBBRRRRAAAARRRRYYYY____PPPPAAAATTTTHHHH is
examined.
All of these variables are ignored if the process is running sssseeeettttuuuuiiiidddd or
4) the default search paths are used. These are ////uuuussssrrrr////lllliiiibbbb::::////lllliiiibbbb for 32-bit
programs, ////uuuussssrrrr////lllliiiibbbb66664444::::////lllliiiibbbb66664444 for 64-bit programs, and ////uuuussssrrrr////lllliiiibbbb33332222::::////lllliiiibbbb33332222
for new 32-bit ABI programs.
The variable ____RRRRLLLLDDDD____RRRROOOOOOOOTTTT has its usual effect, as documented on rrrrlllldddd(1)
(which means that if the process is running sssseeeettttuuuuiiiidddd or sssseeeettttggggiiiidddd ____RRRRLLLLDDDD____RRRROOOOOOOOTTTT is
If _p_a_t_h_n_a_m_e cannot be found, cannot be opened for reading, is not a
shared object, or if an error occurs during the process of loading
_p_a_t_h_n_a_m_e or relocating its symbolic references, ddddllllooooppppeeeennnn returns NNNNUUUULLLLLLLL.
More detailed diagnostic information is available through ddddlllleeeerrrrrrrroooorrrr.
NNNNOOOOTTTTEEEESSSS
Objects whose names resolve to the same absolute or relative path name
may be opened any number of times using ddddllllooooppppeeeennnn, however, the object
referenced is only loaded once into the address space of the current
process. The same object referenced by two different path names,
however, may be loaded multiple times. For example, given the object
////uuuussssrrrr////hhhhoooommmmeeee////mmmmeeee////mmmmyyyylllliiiibbbbssss////mmmmyyyylllliiiibbbb....ssssoooo, and assuming the current working directory
is ////uuuussssrrrr////hhhhoooommmmeeee////mmmmeeee////wwwwoooorrrrkkkkddddiiiirrrr,